//
//  JwKeychain.m
//  JwPack
//
//  Created by 陈警卫 on 2024-07-31.
//

#import "JwKeychain.h"

@implementation JwKeychain

/// 创建Keychain查询字典
+ (NSMutableDictionary *)keychainQueryForService:(NSString *)service {
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (id)kSecClassGenericPassword, kSecClass,
            service, kSecAttrService,
            service, kSecAttrAccount,
            kSecAttrAccessibleAfterFirstUnlock, kSecAttrAccessible,
            nil];
}

/// 归档对象为NSData
+ (NSData *)archivedDataWithObject:(id)object {
    return [NSKeyedArchiver archivedDataWithRootObject:object];
}

/// 解档NSData为对象
+ (id)unarchivedObjectWithData:(NSData *)data {
    return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

/// 加载服务名相关联的数据项
+ (id)load:(NSString *)service {
    // 获取Keychain查询字典
    NSMutableDictionary *query = [self keychainQueryForService:service];
    // 设置返回数据和匹配限制
    [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
    [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&keyData);
    if (status == errSecSuccess) {
        NSData *data = (__bridge_transfer NSData *)keyData;
        id result = [self unarchivedObjectWithData:data];
        return result;
    } else {
        NSLog(@"JwKeychain -- Failed to load data from Keychain for service '%@': %d", service, (int)status);
        return nil;
    }
}

/// 保存服务名相关联的数据项
+ (void)save:(NSString *)service data:(id)data {
    // 获取Keychain查询字典
    NSMutableDictionary *query = [self keychainQueryForService:service];
    // 归档数据
    NSData *archivedData = [self archivedDataWithObject:data];
    // 设置数据
    [query setObject:archivedData forKey:(id)kSecValueData];
    OSStatus status = SecItemAdd((CFDictionaryRef)query, NULL);
    if (status != errSecSuccess) {
        NSLog(@"JwKeychain -- Failed to save data to Keychain for service '%@': %d", service, (int)status);
    }
}

/// 删除与服务名相关联的数据项
+ (void)deleteKeyData:(NSString *)service {
    // 获取Keychain查询字典
    NSMutableDictionary *query = [self keychainQueryForService:service];
    OSStatus status = SecItemDelete((CFDictionaryRef)query);
    if (status != errSecSuccess) {
        NSLog(@"JwKeychain -- Failed to delete data from Keychain for service '%@': %d", service, (int)status);
    }
}

@end
